home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Frameworks / Sprocket Framework DR2 / Sprocket Framework / AEThreads.cp < prev    next >
Text File  |  1996-06-15  |  5KB  |  202 lines

  1. /*
  2.  
  3.     File:        AEThreads.cp
  4.     Project:    Sprocket Framework 1.1 (DR2), released 6/15/96
  5.     Contains:    Routines for installing threaded AppleEvent handlers
  6.     To Do:        To really support AppleScript™, we’ll need to do ALOT more work in here.
  7.  
  8.     Sprocket Major Contributors:
  9.     ----------------------------
  10.     Dave Falkenburg, producer of Sprocket 1.0
  11.     Bill Hayden,     producer of Sprocket 1.1
  12.     Steve Sisak,     producer of the upcoming Sprocket 2.0
  13.     
  14.     Pete Alexander        Steve Falkenburg    Randy Thelen
  15.     Eric Berdahl        Nitin Ganatra        Chris K. Thomas
  16.     Marshall Clow        Dave Hershey        Leonard Rosenthal
  17.     Tim Craycroft        Dave Mark            Dean Yu
  18.     David denBoer        Gary Powell
  19.     Cameron Esfahani    Jon Summers            Apple Computer, Inc.
  20.         
  21.     Comments, Additions, or Corrections:
  22.     ------------------------------------
  23.     Bill Hayden, Nikol Software <nikol@codewell.com>
  24.  
  25. */
  26.  
  27.  
  28.  
  29. #ifndef __AETHREADS__
  30. #include "AEThreads.h"
  31. #endif
  32. #ifndef __ERRORS__
  33. #include <Errors.h>
  34. #endif
  35. #ifndef __APPLEEVENTS__
  36. #include <AppleEvents.h>
  37. #endif
  38.  
  39. #include "ThreadContext.h"
  40. #include "SprocketMacros.h"
  41.  
  42.  
  43. pascal OSErr SpawnAEThread(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
  44.  
  45. class AEThreadContext : public TThreadContext
  46. {
  47. protected:
  48.     AEEventHandlerUPP    fHandler;    // The real handler
  49.     const AppleEvent*    fEvent;
  50.     AppleEvent*            fReply;
  51.     long                fRefcon;
  52.  
  53. public:
  54.     AEThreadContext(AEEventHandlerUPP handler, const AppleEvent* event, AppleEvent* reply, long refcon) : fHandler(handler), fEvent(event), fReply(reply), fRefcon(refcon) {};
  55.     virtual    ~AEThreadContext() {};
  56.     
  57.     static pascal void*            AEThreadProc(AEThreadContext* context);
  58.  
  59.     friend pascal OSErr SpawnAEThread(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
  60. };
  61.  
  62. struct AEThreadDesc                    // Kept in the OS refcon
  63. {
  64.     AEEventHandlerUPP    handler;    // The real handler
  65.     long                refcon;        // The real refcon
  66.     Size                stackSize;    // Stack size for handling event
  67.     ThreadOptions        options;    // Thread options for event
  68.     ThreadID            holder;        // used as a semaphore
  69. };
  70.  
  71. AEEventHandlerUPP gSpawnAEThreadUPP = nil;
  72.  
  73.  
  74.  
  75. /*****************************************************************************/
  76.  
  77.  
  78.  
  79. pascal OSErr AEInstallThreadedEventHandler( AEEventClass        theAEEventClass,
  80.                                             AEEventID            theAEEventID,
  81.                                             AEEventHandlerUPP    proc,
  82.                                             long                handlerRefcon,
  83.                                             ThreadOptions        options,
  84.                                             Size                stacksize)
  85. {
  86.     AEThreadDesc* desc = (AEThreadDesc*) NewPtr(sizeof(AEThreadDesc));
  87.     OSErr          err  = MemError();
  88.     
  89.     if (gSpawnAEThreadUPP == nil)
  90.         {
  91.         gSpawnAEThreadUPP = NewAEEventHandlerProc(SpawnAEThread);
  92.         }
  93.     
  94.     if (err == noErr)
  95.         {
  96.         desc->handler    = proc;
  97.         desc->refcon    = handlerRefcon;
  98.         desc->stackSize    = stacksize;
  99.         desc->options    = options;
  100.         desc->holder    = kNoThreadID;
  101.  
  102.         err = AEInstallEventHandler(theAEEventClass, theAEEventID, gSpawnAEThreadUPP, (long) desc, false);
  103.         }
  104.     
  105.     return err;
  106. }
  107.  
  108.  
  109.  
  110. /*****************************************************************************/
  111.  
  112.  
  113.  
  114. pascal void* AEThreadContext::AEThreadProc(AEThreadContext* context)
  115. {
  116.     OSErr result = noErr;
  117.  
  118.     try
  119.         {
  120.         result = CallAEEventHandlerProc(context->fHandler, context->fEvent, context->fReply, context->fRefcon);
  121.  
  122.         // Since the event was suspended, we need to stuff the error code ourselves    
  123.         // note that there's not much we can do about reporting errors beyond here
  124.         }
  125.     catch(OSErr err)
  126.         {
  127.         result = err;
  128.         }
  129.     
  130.     OSErr err;
  131.         
  132.     err = AEPutAttributePtr(context->fReply, keyErrorNumber, typeShortInteger, &result, sizeof(result));
  133.  
  134.     if (err)
  135.         DebugMessage("\pAEPutAttributePtr failed installing error code - very bad");
  136.  
  137.     err = AEResumeTheCurrentEvent(context->fEvent, context->fReply, kAENoDispatch, 0);    // This had better work
  138.  
  139.     if (err)
  140.         DebugMessage("\pAEResumeTheCurrentEvent failed - very bad");
  141.  
  142.     delete context;
  143.  
  144.     return nil;
  145. }
  146.  
  147.  
  148.  
  149. /*****************************************************************************/
  150.  
  151.  
  152.  
  153. pascal OSErr AEHandleInThread(  const AppleEvent*    event,
  154.                                 AppleEvent*            reply,
  155.                                 AEEventHandlerUPP    handler,
  156.                                 long                handlerRefcon,
  157.                                 ThreadOptions        options,
  158.                                 Size                stacksize)
  159. {
  160.     OSErr             result;
  161.     AEThreadContext* context = new AEThreadContext(handler, event, reply, handlerRefcon);
  162.     
  163.     try
  164.         {
  165.         if (!context)
  166.             throw(nilHandleErr);
  167.     
  168.         context->CreateThread(kCooperativeThread, (ThreadEntryProcPtr) AEThreadContext::AEThreadProc, stacksize, options);
  169.  
  170.         result = AESuspendTheCurrentEvent(event);
  171.         }
  172.     catch(OSErr err)
  173.         {
  174.         delete context;
  175.  
  176.         result = err;
  177.         }
  178.     
  179.     return result;
  180. }
  181.  
  182.  
  183.  
  184. /*****************************************************************************/
  185.  
  186.  
  187.  
  188. pascal OSErr SpawnAEThread(const AppleEvent *event, AppleEvent *reply, long handlerRefcon)
  189. {
  190.     AEThreadDesc* desc = (AEThreadDesc*) handlerRefcon;
  191.  
  192.      return AEHandleInThread(event, reply,
  193.                             desc->handler,
  194.                             desc->refcon,
  195.                             desc->options,
  196.                             desc->stackSize);
  197. }
  198.  
  199.  
  200.  
  201.  
  202.